#!/usr/bin/env python
# -*- coding: utf-8 -*-
#===============================================================================
# Copyright 2011 zod.yslin
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 
# Author: zod.yslin
# Email: 
# File Name: inheritance.py
# Description: 
# 
# Edit History: 
#   2011-08-09    File created.
#===============================================================================

class BaseClassName:
    __x = 0
    def __init__(self):   
        self.data = "base"
        BaseClassName.__x += 1
        self.__update("hello __update")
        self.update("hello update")

    def update(self, msg):
        print msg

    __update = update   # private copy of original update() method    

    @classmethod
    def getX(cls):
        return cls.__x

class DerivedClassName(BaseClassName): # (modname.BaseClassName), or mutiple inheritance (Base1, Base2, Base3)

    """
    It will override BaseClassName update methods, when call by DerivedClassName object
    """
    def update(self, msg):
        # provides new signature for update()
        # but does not break __init__()
        print "[new]:" + msg
            
parent = BaseClassName()
print parent.getX()
child = DerivedClassName()
print child.getX()
print isinstance(child, BaseClassName)  # True
print isinstance(parent, BaseClassName)  # True

print isinstance(child, DerivedClassName)  # True
print isinstance(parent, DerivedClassName)  # False

print issubclass(DerivedClassName, BaseClassName) # True
print issubclass(BaseClassName, DerivedClassName) # False

print issubclass(unicode, str) # False since unicode is not a subclass of str (they only share a common ancestor, basestring
print issubclass(unicode, basestring) # True

#==============================================================================
# Private Variables
# “Private” instance variables that cannot be accessed except from inside an 
# object don’t exist in Python. 
# However, there is a convention that is followed by most Python code: 
#    a name prefixed with an underscore (e.g. _spam) should be treated as a
#    non-public part of the API (whether it is a function, a method or a data member). 
#==============================================================================
child.update("test")
parent.update("google")

